package com.jackrain.nea.web.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jackrain.nea.config.Resources;
import com.jackrain.nea.core.query.ColumnLink;
import com.jackrain.nea.core.schema.Column;
import com.jackrain.nea.core.schema.Table;
import com.jackrain.nea.core.schema.TableManager;
import com.jackrain.nea.core.schema.TriggerHolder;
import com.jackrain.nea.core.webaction.WebAction;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.ext.permission.Permissions;
import com.jackrain.nea.util.Tools;
import com.jackrain.nea.util.Validator;
import com.jackrain.nea.util.ValueHolder;
import com.jackrain.nea.web.common.AjaxUtils;
import com.jackrain.nea.web.common.Handle;
import com.jackrain.nea.web.common.WebIntercept;
import com.jackrain.nea.web.face.User;
import com.jackrain.nea.web.face.impl.UserImpl;
import com.jackrain.nea.web.query.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static com.jackrain.nea.ext.permission.Permissions.getWritableDatas;

@Slf4j
@RestController
@Api(value = "CommandController", description = "单对象事务处理")
public class CommandController {

    @Autowired
    private Handle handle;

    @ApiOperation(value = "单对象保存", notes = "param:{\n" + "  \"objid\":123||-1,\n" + "  \"fixcolumn\": {\n" + "    \"C_STORE\": {\n" + "      \"NAME\": \"沧州 \",\n" + "      \"CODE\": \"00009\"\n" + "    },\n" + "    \"C_STOREITEM\": [\n" + "      {\n" + "\"ID\": -1,\n" + "        \"AMT\": 100\n" + "      },\n" + "      {\n" + "\"ID\": 2,\n" + "        \"AMT2\": 3456\n" + "      }\n" + "    ]\n" + "  }\n" + "}\n")
    @RequestMapping(path = "/p/cs/objectSave", method = {RequestMethod.GET, RequestMethod.POST})
    public JSONObject doSave(HttpServletRequest request,
                             @RequestParam(value = "table", required = true) String tablename,
                             @RequestParam(value = "objid", required = true) Long objid,
                             @RequestParam(value = "data", required = true) String data,
                             @RequestParam(value = "command", required = false) String command,
                             @RequestParam(value = "before", required = false) String before,
                             @RequestParam(value = "after", required = false) String after) throws Exception {


        ValueHolder valueHolder = new ValueHolder();
        TriggerHolder.VersionedTrigger trigger = null;

        String key = WebIntercept.generateKey(request);
        if(!WebIntercept.checkKey(request)){
            valueHolder.put("code",-1);
            valueHolder.put("message","请勿连续点击！");
            return valueHolder.toJSONObject();
        }

        try {
            UserImpl userWeb = (UserImpl) request.getSession().getAttribute("user");

            QuerySession qsession = QueryUtils.createQuerySession(userWeb);

            TableManager tm = qsession.getTableManager();

            Table table = tm.getTable(tablename);

            objid = Tools.getLong(objid, -1);

            if (objid < 0) {
                throw new NDSException("objid -1");
            }

            JSONObject fixcolumn = JSON.parseObject(data);
            JSONObject beforevalue = JSON.parseObject(before);
            JSONObject aftervalue = JSON.parseObject(after);

            JSONObject jor = new JSONObject();
            jor.put("objid", objid);
            jor.put("fixcolumn", fixcolumn);
            jor.put("beforevalue", beforevalue);
            jor.put("aftervalue", aftervalue);
            jor.put("table", table.getName());


            trigger = table.getTrigger("TRI");

            if (trigger != null) {
                jor.put("aspecttrigger", trigger.toJSONObject());
            }

            DefaultWebEvent event = new DefaultWebEvent("doSave", request, false);

            event.put("param", jor);

            valueHolder = handle.process(jor, qsession, event, "save");

            int code = Tools.getInt(String.valueOf(valueHolder.get("code")), 0);

            if (code == 0) {
                valueHolder.put("message", Resources.getMessage("保存成功", qsession.getLocale()));
            }

            return valueHolder.toJSONObject();

        } catch (Exception e) {
            log.error(e.getMessage(),e);
            if(e instanceof NDSException){
                valueHolder.put("code",-1);
                valueHolder.put("message",((NDSException) e).getSimpleMessage());
            }else{
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                e.printStackTrace(pw);
                valueHolder.put("code",-2);
                valueHolder.put("message",sw.toString().replace("\n","<br/>")
                        .replace("\tat",""));
            }
            return valueHolder.toJSONObject();
        }
    }

    @ApiOperation(value = "单对象新增")
    @RequestMapping(path = "/p/cs/objectAdd", method = {RequestMethod.GET, RequestMethod.POST})
    public JSONObject doAdd(HttpServletRequest request, @RequestParam(value = "table", required = true) String tablename, @RequestParam(value = "objid", required = true) Long objid, @RequestParam(value = "data", required = true) String data, @RequestParam(value = "command", required = false) String command) throws Exception {
        ValueHolder valueHolder = new ValueHolder();
        TriggerHolder.VersionedTrigger trigger = null;

        String key = WebIntercept.generateKey(request);
        if(!WebIntercept.checkKey(request)){
            valueHolder.put("code",-1);
            valueHolder.put("message","请勿连续点击！");
            return valueHolder.toJSONObject();
        }
        try {
            UserImpl userWeb = (UserImpl) request.getSession().getAttribute("user");

            QuerySession qsession = QueryUtils.createQuerySession(userWeb);

            TableManager tm = qsession.getTableManager();

            Table table = tm.getTable(tablename);

            objid = Tools.getLong(objid, -1);

//            if(objid<0){
//                throw new NDSException("objid -1");
//            }

            JSONObject fixcolumn = JSON.parseObject(data);


            //增加界面不显示字段默认值传入，识别第6位
            ArrayList columns = table.getColumns(new int[]{6}, false, 0, true);

            columns.forEach(item -> {
                String val = ((Column) item).getDefaultValue();
                //if(val.contains("$")){
                val = QueryUtils.replaceVariables(val, qsession);
                //}
                fixcolumn.getJSONObject(table.getName()).put(((Column) item).getName(), val);
            });

            JSONObject jor = new JSONObject();
            jor.put("objid", objid);
            jor.put("fixcolumn", fixcolumn);
            jor.put("table", table.getName());


            trigger = table.getTrigger("TRI");

            if (trigger != null) {
                jor.put("aspecttrigger", trigger.toJSONObject());
            }

            DefaultWebEvent event = new DefaultWebEvent("doAdd", request, false);

            event.put("param", jor);

            valueHolder = handle.process(jor, qsession, event, "add");

            int code = Tools.getInt(String.valueOf(valueHolder.get("code")), 0);

            if (code == 0) {
                valueHolder.put("message", Resources.getMessage("保存成功", qsession.getLocale()));
            }
            return valueHolder.toJSONObject();

        } catch (Exception e) {
            log.error(e.getMessage(),e);
            if(e instanceof NDSException){
                valueHolder.put("code",-1);
                valueHolder.put("message",((NDSException) e).getSimpleMessage());
            }else{
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                e.printStackTrace(pw);
                valueHolder.put("code",-2);
                valueHolder.put("message",sw.toString().replace("\n","<br/>")
                        .replace("\tat",""));
            }
            return valueHolder.toJSONObject();
        }
    }


    @ApiOperation(value = "单对象删除")
    @RequestMapping(path = "/p/cs/objectDelete", method = {RequestMethod.GET, RequestMethod.POST})
    public JSONObject doDelete(HttpServletRequest request, @RequestParam(value = "table", required = true) String tablename, @RequestParam(value = "objid", required = true) Long objid, @RequestParam(value = "data", required = false) String data, @RequestParam(value = "command", required = false) String command, @RequestParam(value = "isdelmtable", required = false, defaultValue = "true") String isdelmtable) throws Exception {
        ValueHolder valueHolder = new ValueHolder();
        TriggerHolder.VersionedTrigger trigger = null;

        String key = WebIntercept.generateKey(request);
        if(!WebIntercept.checkKey(request)){
            valueHolder.put("code",-1);
            valueHolder.put("message","请勿连续点击！");
            return valueHolder.toJSONObject();
        }
        try {
            UserImpl userWeb = (UserImpl) request.getSession().getAttribute("user");

            QuerySession qsession = QueryUtils.createQuerySession(userWeb);

            TableManager tm = qsession.getTableManager();

            Table table = tm.getTable(tablename);

            objid = Tools.getLong(objid, -1);

            if (objid < 0) {
                throw new NDSException("objid -1");
            }

            JSONObject tabitem = JSON.parseObject(data);

            JSONObject jor = new JSONObject();
            jor.put("objid", objid);
            if (tabitem != null) {
                jor.put("tabitem", tabitem);
            }
            jor.put("table", table.getName());
            jor.put("isdelmtable", Tools.getBoolean(isdelmtable, true));


            trigger = table.getTrigger("TRI");

            if (trigger != null) {
                jor.put("aspecttrigger", trigger.toJSONObject());
            }

            DefaultWebEvent event = new DefaultWebEvent("doDelete", request, false);

            event.put("param", jor);

            valueHolder = handle.process(jor, qsession, event, "delete");

            int code = Tools.getInt(String.valueOf(valueHolder.get("code")), 0);


            if (code == 0) {
                valueHolder.put("message", Resources.getMessage("删除成功", qsession.getLocale()));
            }

            return valueHolder.toJSONObject();

        } catch (Exception e) {
            log.error(e.getMessage(),e);
            if(e instanceof NDSException){
                valueHolder.put("code",-1);
                valueHolder.put("message",((NDSException) e).getSimpleMessage());
            }else{
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                e.printStackTrace(pw);
                valueHolder.put("code",-2);
                valueHolder.put("message",sw.toString().replace("\n","<br/>")
                        .replace("\tat",""));
            }
            return valueHolder.toJSONObject();
        }
    }

    @ApiOperation(value = "单对象提交")
    @RequestMapping(path = "/p/cs/objectSubmit", method = {RequestMethod.GET, RequestMethod.POST})
    public JSONObject doSubmit(HttpServletRequest request, @RequestParam(value = "table", required = true) String tablename, @RequestParam(value = "objid", required = true) Long objid, @RequestParam(value = "command", required = false) String command) throws Exception {
        ValueHolder valueHolder = new ValueHolder();
        TriggerHolder.VersionedTrigger trigger = null;

        String key = WebIntercept.generateKey(request);
        if(!WebIntercept.checkKey(request)){
            valueHolder.put("code",-1);
            valueHolder.put("message","请勿连续点击！");
            return valueHolder.toJSONObject();
        }
        try {
            UserImpl userWeb = (UserImpl) request.getSession().getAttribute("user");

            QuerySession qsession = QueryUtils.createQuerySession(userWeb);

            TableManager tm = qsession.getTableManager();

            Table table = tm.getTable(tablename);

            objid = Tools.getLong(objid, -1);

            if (objid < 0) {
                throw new NDSException("objid -1");
            }

            //JSONObject fixcolumn= JSON.parseObject(data);


            JSONObject jor = new JSONObject();
            jor.put("objid", objid);
            jor.put("table", table.getName());


            trigger = table.getTrigger("TRI");

            if (trigger != null) {
                jor.put("aspecttrigger", trigger.toJSONObject());
            }

            DefaultWebEvent event = new DefaultWebEvent("doSubmit", request, false);

            event.put("param", jor);

            int code = Tools.getInt(String.valueOf(valueHolder.get("code")), 0);


            if (code == 0) {
                valueHolder.put("message", Resources.getMessage("提交成功", qsession.getLocale()));
            }

            valueHolder = handle.process(jor, qsession, event, "submit");

            return valueHolder.toJSONObject();

        } catch (Exception e) {
            log.error(e.getMessage(),e);
            if(e instanceof NDSException){
                valueHolder.put("code",-1);
                valueHolder.put("message",((NDSException) e).getSimpleMessage());
            }else{
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                e.printStackTrace(pw);
                valueHolder.put("code",-2);
                valueHolder.put("message",sw.toString().replace("\n","<br/>")
                        .replace("\tat",""));
            }
            return valueHolder.toJSONObject();
        }
    }

    @ApiOperation(value = "单对象作废")
    @RequestMapping(path = "/p/cs/objectVoid", method = {RequestMethod.GET, RequestMethod.POST})
    public JSONObject doVoid(HttpServletRequest request, @RequestParam(value = "table", required = true) String tablename, @RequestParam(value = "objid", required = true) Long objid, @RequestParam(value = "command", required = false) String command) throws Exception {
        ValueHolder valueHolder = new ValueHolder();
        TriggerHolder.VersionedTrigger trigger = null;

        String key = WebIntercept.generateKey(request);
        if(!WebIntercept.checkKey(request)){
            valueHolder.put("code",-1);
            valueHolder.put("message","请勿连续点击！");
            return valueHolder.toJSONObject();
        }
        try {
            UserImpl userWeb = (UserImpl) request.getSession().getAttribute("user");

            QuerySession qsession = QueryUtils.createQuerySession(userWeb);

            TableManager tm = qsession.getTableManager();

            Table table = tm.getTable(tablename);

            objid = Tools.getLong(objid, -1);

            if (objid < 0) {
                throw new NDSException("objid -1");
            }

            //JSONObject fixcolumn= JSON.parseObject(data);


            JSONObject jor = new JSONObject();
            jor.put("objid", objid);
            jor.put("table", table.getName());


            trigger = table.getTrigger("TRI");

            if (trigger != null) {
                jor.put("aspecttrigger", trigger.toJSONObject());
            }

            DefaultWebEvent event = new DefaultWebEvent("doVoid", request, false);

            event.put("param", jor);

            valueHolder = handle.process(jor, qsession, event, "void");

            int code = Tools.getInt(String.valueOf(valueHolder.get("code")), 0);


            if (code == 0) {
                valueHolder.put("message", Resources.getMessage("作废成功", qsession.getLocale()));
            }

            return valueHolder.toJSONObject();

        } catch (Exception e) {
            log.error(e.getMessage(),e);
            if(e instanceof NDSException){
                valueHolder.put("code",-1);
                valueHolder.put("message",((NDSException) e).getSimpleMessage());
            }else{
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                e.printStackTrace(pw);
                valueHolder.put("code",-2);
                valueHolder.put("message",sw.toString().replace("\n","<br/>")
                        .replace("\tat",""));
            }
            return valueHolder.toJSONObject();
        }
    }

    @ApiOperation(value = "单对象反提交")
    @RequestMapping(path = "/p/cs/objectUnSubmit", method = {RequestMethod.GET, RequestMethod.POST})
    public JSONObject doUnSubmit(HttpServletRequest request, @RequestParam(value = "table", required = true) String tablename, @RequestParam(value = "objid", required = true) Long objid, @RequestParam(value = "command", required = false) String command) throws Exception {
        ValueHolder valueHolder = new ValueHolder();
        TriggerHolder.VersionedTrigger trigger = null;

        String key = WebIntercept.generateKey(request);
        if(!WebIntercept.checkKey(request)){
            valueHolder.put("code",-1);
            valueHolder.put("message","请勿连续点击！");
            return valueHolder.toJSONObject();
        }
        try {
            UserImpl userWeb = (UserImpl) request.getSession().getAttribute("user");

            QuerySession qsession = QueryUtils.createQuerySession(userWeb);

            TableManager tm = qsession.getTableManager();

            Table table = tm.getTable(tablename);

            objid = Tools.getLong(objid, -1);

            if (objid < 0) {
                throw new NDSException("objid -1");
            }

            //JSONObject fixcolumn= JSON.parseObject(data);


            JSONObject jor = new JSONObject();
            jor.put("objid", objid);
            jor.put("table", table.getName());


            trigger = table.getTrigger("TRI");

            if (trigger != null) {
                jor.put("aspecttrigger", trigger.toJSONObject());
            }

            DefaultWebEvent event = new DefaultWebEvent("doUnSubmit", request, false);

            event.put("param", jor);

            valueHolder = handle.process(jor, qsession, event, "unsubmit");

            return valueHolder.toJSONObject();

        } catch (Exception e) {
            log.error(e.getMessage(),e);
            if(e instanceof NDSException){
                valueHolder.put("code",-1);
                valueHolder.put("message",((NDSException) e).getSimpleMessage());
            }else{
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                e.printStackTrace(pw);
                valueHolder.put("code",-2);
                valueHolder.put("message",sw.toString().replace("\n","<br/>")
                        .replace("\tat",""));
            }
            return valueHolder.toJSONObject();
        }
    }

    @ApiOperation(value = "批量删除")
    @RequestMapping(path = "/p/cs/batchDelete", method = {RequestMethod.GET, RequestMethod.POST})
    public JSONObject doBatchDelete(HttpServletRequest request,
                                    @RequestParam(value = "table", required = true) String tablename,
                                    @RequestParam(value = "objids", required = true) String objids,
                                    @RequestParam(value = "command", required = false) String command,
                                    @RequestParam(value = "isdelmtable", required = false, defaultValue = "true") String isdelmtable) throws Exception {
        ValueHolder result = new ValueHolder();

        String key = WebIntercept.generateKey(request);
        if(!WebIntercept.checkKey(request)){
            result.put("code",-1);
            result.put("message","请勿连续点击！");
            return result.toJSONObject();
        }
        UserImpl userWeb = (UserImpl) request.getSession().getAttribute("user");
        QuerySession qsession = QueryUtils.createQuerySession(userWeb);
        TableManager tm = qsession.getTableManager();
        Table table = tm.getTable(tablename);
        String[] ids = objids.split(",");

        JSONArray errJa = new JSONArray();

        for (int i = 0; i < ids.length; i++) {
            JSONObject errJo = new JSONObject();
            Long objid = Tools.getLong(ids[i], -1);
            if (objid < 0) {
                continue;
            }
            JSONObject jor = new JSONObject();
            jor.put("objid", objid);
            jor.put("table", table.getName());
            jor.put("isdelmtable", Tools.getBoolean(isdelmtable, true));

            TriggerHolder.VersionedTrigger trigger = table.getTrigger("TRI");
            if (trigger != null) {
                jor.put("aspecttrigger", trigger.toJSONObject());
            }

            DefaultWebEvent event = new DefaultWebEvent("doDelete", request, false);
            event.put("param", jor);

            try {
                ValueHolder valueHolder = handle.process(jor, qsession, event, "delete");
                int code = Tools.getInt(String.valueOf(valueHolder.get("code")), 0);
                if (code < 0) {
                    errJo.put("objid", objid);
                    errJo.put("message", valueHolder.get("message"));
                    errJa.add(errJo);
                }
            } catch (Exception e) {
                log.error(e.getMessage(),e);
                if(e instanceof NDSException){
                    errJo.put("objid", objid);
                    errJo.put("message", ((NDSException) e).getSimpleMessage());
                }else{
                    StringWriter sw = new StringWriter();
                    PrintWriter pw = new PrintWriter(sw);
                    e.printStackTrace(pw);
                    errJo.put("objid", objid);
                    errJo.put("message",sw.toString().replace("\n","<br/>")
                            .replace("\tat",""));
                }
                errJa.add(errJo);
            }
        }

        if (errJa.size() > 0) {
            result.put("code", -1);
            result.put("data", errJa);
            result.put("message", "删除成功记录数：" + (ids.length - errJa.size()) + "，删除失败记录数：" + errJa.size());
        } else {
            result.put("code", 0);
            result.put("message", "删除成功记录数：" + ids.length);

        }

        return result.toJSONObject();

    }

    @ApiOperation(value = "批量提交")
    @RequestMapping(path = "/p/cs/batchSubmit", method = {RequestMethod.GET, RequestMethod.POST})
    public JSONObject doBatchSubmit(HttpServletRequest request,
                                    @RequestParam(value = "table", required = true) String tablename,
                                    @RequestParam(value = "objids", required = true) String objids,
                                    @RequestParam(value = "command", required = false) String command) throws Exception {
        ValueHolder result = new ValueHolder();

        String key = WebIntercept.generateKey(request);
        if(!WebIntercept.checkKey(request)){
            result.put("code",-1);
            result.put("message","请勿连续点击！");
            return result.toJSONObject();
        }
        UserImpl userWeb = (UserImpl) request.getSession().getAttribute("user");
        QuerySession qsession = QueryUtils.createQuerySession(userWeb);
        TableManager tm = qsession.getTableManager();
        Table table = tm.getTable(tablename);

        String[] ids = objids.split(",");

        JSONArray errJa = new JSONArray();

        for (int i = 0; i < ids.length; i++) {
            JSONObject errJo = new JSONObject();
            Long objid = Tools.getLong(ids[i], -1);
            if (objid < 0) {
                continue;
            }

            JSONObject jor = new JSONObject();
            jor.put("objid", objid);
            jor.put("table", table.getName());

            TriggerHolder.VersionedTrigger trigger = table.getTrigger("TRI");

            if (trigger != null) {
                jor.put("aspecttrigger", trigger.toJSONObject());
            }

            DefaultWebEvent event = new DefaultWebEvent("doSubmit", request, false);
            event.put("param", jor);

            try {
                ValueHolder valueHolder = handle.process(jor, qsession, event, "submit");
                int code = Tools.getInt(String.valueOf(valueHolder.get("code")), 0);
                if (code < 0) {
                    errJo.put("objid", objid);
                    errJo.put("message", valueHolder.get("message"));
                    errJa.add(errJo);
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                if(e instanceof NDSException){
                    errJo.put("objid", objid);
                    errJo.put("message", ((NDSException) e).getSimpleMessage());
                }else{
                    StringWriter sw = new StringWriter();
                    PrintWriter pw = new PrintWriter(sw);
                    e.printStackTrace(pw);
                    errJo.put("objid", objid);
                    errJo.put("message",sw.toString().replace("\n","<br/>")
                            .replace("\tat",""));
                }
                errJa.add(errJo);
            }
        }

        if (errJa.size() > 0) {
            result.put("code", -1);
            result.put("data", errJa);
            result.put("message", "提交成功记录数：" + (ids.length - errJa.size()) + "，提交失败记录数：" + errJa.size());
        } else {
            result.put("code", 0);
            result.put("message", "提交成功记录数：" + ids.length);
        }

        return result.toJSONObject();

    }

    @ApiOperation(value = "批量作废")
    @RequestMapping(path = "/p/cs/batchVoid", method = {RequestMethod.GET, RequestMethod.POST})
    public JSONObject doBatchVoid(HttpServletRequest request, @RequestParam(value = "table", required = true) String tablename, @RequestParam(value = "objids", required = true) String objids, @RequestParam(value = "command", required = false) String command) throws Exception {
        ValueHolder result = new ValueHolder();

        String key = WebIntercept.generateKey(request);
        if(!WebIntercept.checkKey(request)){
            result.put("code",-1);
            result.put("message","请勿连续点击！");
            return result.toJSONObject();
        }
        UserImpl userWeb = (UserImpl) request.getSession().getAttribute("user");
        QuerySession qsession = QueryUtils.createQuerySession(userWeb);
        TableManager tm = qsession.getTableManager();
        Table table = tm.getTable(tablename);


        String[] ids = objids.split(",");

        JSONArray errJa = new JSONArray();

        for (int i = 0; i < ids.length; i++) {
            JSONObject errJo = new JSONObject();
            Long objid = Tools.getLong(ids[i], -1);
            if (objid < 0) {
                continue;
            }

            JSONObject jor = new JSONObject();
            jor.put("objid", objid);
            jor.put("table", table.getName());

            TriggerHolder.VersionedTrigger trigger = table.getTrigger("TRI");

            if (trigger != null) {
                jor.put("aspecttrigger", trigger.toJSONObject());
            }

            DefaultWebEvent event = new DefaultWebEvent("doVoid", request, false);
            event.put("param", jor);

            try {
                ValueHolder valueHolder = handle.process(jor, qsession, event, "void");
                int code = Tools.getInt(String.valueOf(valueHolder.get("code")), 0);
                if (code < 0) {
                    errJo.put("objid", objid);
                    errJo.put("message", valueHolder.get("message"));
                    errJa.add(errJo);
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                if(e instanceof NDSException){
                    errJo.put("objid", objid);
                    errJo.put("message", ((NDSException) e).getSimpleMessage());
                }else{
                    StringWriter sw = new StringWriter();
                    PrintWriter pw = new PrintWriter(sw);
                    e.printStackTrace(pw);
                    errJo.put("objid", objid);
                    errJo.put("message",sw.toString().replace("\n","<br/>")
                            .replace("\tat",""));
                }
                errJa.add(errJo);
            }
        }

        if (errJa.size() > 0) {
            result.put("code", -1);
            result.put("data", errJa);
            result.put("message", "作废成功记录数：" + (ids.length - errJa.size()) + "，作废失败记录数：" + errJa.size());
        } else {
            result.put("code", 0);
            result.put("message", "作废成功记录数：" + ids.length);

        }

        return result.toJSONObject();
    }

    @ApiOperation(value = "批量反提交")
    @RequestMapping(path = "/p/cs/batchUnSubmit", method = {RequestMethod.GET, RequestMethod.POST})
    public JSONObject doBatchUnSubmit(HttpServletRequest request,
                                      @RequestParam(value = "table", required = true) String tablename,
                                      @RequestParam(value = "objids", required = true) String objids,
                                      @RequestParam(value = "command", required = false) String command) throws Exception {
        ValueHolder result = new ValueHolder();

        String key = WebIntercept.generateKey(request);
        if(!WebIntercept.checkKey(request)){
            result.put("code",-1);
            result.put("message","请勿连续点击！");
            return result.toJSONObject();
        }
        UserImpl userWeb = (UserImpl) request.getSession().getAttribute("user");
        QuerySession qsession = QueryUtils.createQuerySession(userWeb);
        TableManager tm = qsession.getTableManager();
        Table table = tm.getTable(tablename);

        String[] ids = objids.split(",");
        JSONArray errJa = new JSONArray();

        for (int i = 0; i < ids.length; i++) {
            JSONObject errJo = new JSONObject();
            Long objid = Tools.getLong(ids[i], -1);
            if (objid < 0) {
                continue;
            }
            JSONObject jor = new JSONObject();
            jor.put("objid", objid);
            jor.put("table", table.getName());


            TriggerHolder.VersionedTrigger trigger = table.getTrigger("TRI");
            if (trigger != null) {
                jor.put("aspecttrigger", trigger.toJSONObject());
            }

            DefaultWebEvent event = new DefaultWebEvent("doUnSubmit", request, false);
            event.put("param", jor);

            try {
                ValueHolder valueHolder = handle.process(jor, qsession, event, "unsubmit");
                int code = Tools.getInt(String.valueOf(valueHolder.get("code")), 0);
                if (code < 0) {
                    errJo.put("objid", objid);
                    errJo.put("message", valueHolder.get("message"));
                    errJa.add(errJo);
                }
            } catch (Exception e) {
                log.error(e.getMessage(),e);
                if(e instanceof NDSException){
                    errJo.put("objid", objid);
                    errJo.put("message", ((NDSException) e).getSimpleMessage());
                }else{
                    StringWriter sw = new StringWriter();
                    PrintWriter pw = new PrintWriter(sw);
                    e.printStackTrace(pw);
                    errJo.put("objid", objid);
                    errJo.put("message",sw.toString().replace("\n","<br/>")
                            .replace("\tat",""));
                }
                errJa.add(errJo);
            }
        }

        if (errJa.size() > 0) {
            result.put("code", -1);
            result.put("data", errJa);
            result.put("message", "取消提交成功记录数：" + (ids.length - errJa.size()) + "，取消提交失败记录数：" + errJa.size());
        } else {
            result.put("code", 0);
            result.put("message", "取消提交成功记录数：" + ids.length);

        }

        return result.toJSONObject();
    }


    @ApiOperation(value = "动作定义执行")
    @RequestMapping(path = "/p/cs/exeAction", method = {RequestMethod.GET, RequestMethod.POST})
    public JSONObject doExeAction(HttpServletRequest request,
                                  @RequestParam(value = "actionid", required = false) int actionid,
                                  @RequestParam(value = "webaction", required = false) String webaction,
                                  @RequestParam(value = "param", required = false) String param) throws Exception {
        ValueHolder result = new ValueHolder();

        if(!WebIntercept.checkKey(request)){
            result.put("code",-1);
            result.put("message","请勿连续点击！");
            return result.toJSONObject();
        }
        UserImpl userWeb = (UserImpl) request.getSession().getAttribute("user");
        QuerySession qsession = QueryUtils.createQuerySession(userWeb);
        TableManager tm = qsession.getTableManager();
        WebAction action = tm.getWebAction(actionid);

        if (action == null) {
            action = tm.getWebAction(webaction);
        }

        DefaultWebEvent event = new DefaultWebEvent("exeAction", request, false);

        JSONObject jor = JSON.parseObject(param);

        event.put("param", jor);

        try {

            if (action.getActionType().equals(WebAction.ActionTypeEnum.BeanShell)) {
                Map alt = action.execute(event.getData());
                ValueHolder finalResult = new ValueHolder();
                alt.forEach((k, v) -> finalResult.put(String.valueOf(k), v));
                return finalResult.toJSONObject();
            } else if (action.getActionType().equals(WebAction.ActionTypeEnum.RPC)) {
                event.setParameter("command", action.getScript());
                event.setParameter("webaction", action.getName());
            }


            result = handle.process(jor, qsession, event, "webaction");

        } catch (Exception e) {
            log.error(e.getMessage(),e);
            if(e instanceof NDSException){
                result.put("code",-1);
                result.put("message",((NDSException) e).getSimpleMessage());
            }else{
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                e.printStackTrace(pw);
                result.put("code",-2);
                result.put("message",sw.toString().replace("\n","<br/>")
                        .replace("\tat",""));
            }
            return result.toJSONObject();
        }

        return result.toJSONObject();
    }

    @ApiOperation(value = "批量保存", notes = "param:{\n" + "  \"objids\":\"1,2,3\",\n" + "  \"fixcolumn\": {\n" + "    \"C_STORE\": {\n" + "      \"NAME\": \"沧州 \",\n" + "      \"CODE\": \"00009\"\n" + "    },\n" + "    \"C_STOREITEM\": [\n" + "      {\n" + "\"ID\": -1,\n" + "        \"AMT\": 100\n" + "      },\n" + "      {\n" + "\"ID\": 2,\n" + "        \"AMT2\": 3456\n" + "      }\n" + "    ]\n" + "  }\n" + "}\n")
    @RequestMapping(path = "/p/cs/batchSave", method = {RequestMethod.GET, RequestMethod.POST})
    public JSONObject doBatchSave(HttpServletRequest request,
                                  @RequestParam(value = "searchdata", required = true) String searchdata,
                                  @RequestParam(value = "data", required = true) String data,
                                  @RequestParam(value = "command", required = false) String command,
                                  @RequestParam(value = "after", required = false) String after) throws Exception {

        ValueHolder resultHolder = new ValueHolder();

        if(!WebIntercept.checkKey(request)){
            resultHolder.put("code",-1);
            resultHolder.put("message","请勿连续点击！");
            return resultHolder.toJSONObject();
        }

        log.debug("===============>searchdata：" + searchdata);
        log.debug("===============>data：" + data);
        log.debug("===============>after：" + after);

        UserImpl userWeb = (UserImpl) request.getSession().getAttribute("user");
        QuerySession qsession = QueryUtils.createQuerySession(userWeb);

        JSONObject searchdataJo = JSONObject.parseObject(searchdata);

        if (searchdataJo == null) {
            resultHolder.put("code", -1);
            resultHolder.put("message", "searchdata参数有误！");
            return resultHolder.toJSONObject();
        }

        String tablename = searchdataJo.getString("table");
        TableManager tm = qsession.getTableManager();
        Table table = tm.getTable(tablename);

        JSONObject afterJo = JSONObject.parseObject(after);

        if (afterJo == null) {
            resultHolder.put("code", -1);
            resultHolder.put("message", "after参数有误！");
            return resultHolder.toJSONObject();
        }

        JSONObject fields = afterJo.getJSONObject(tablename);

        JSONArray objids = null;
        if (searchdataJo.containsKey("objids")) {
            objids = searchdataJo.getJSONArray("objids");
        }

        //优先objids
        if (objids != null && objids.size() > 0) {
//       {"ID":"in (1,99)"}
//       searchdata：{"table":"CP_C_RSTORE","fixedcolumns":{"ISACTIVE":["Y"],"CP_C_DISTRIB_ID":["1112"]},"reffixedcolumns":{},"objids":["2000043","421"]}
//     分页 ({"table":"CP_C_RSTORE","column_include_uicontroller":true,"fixedcolumns":{"ISACTIVE":["Y"],"CP_C_DISTRIB_ID":["1112"]},"startindex":10,"orderby":[{"name":"CP_C_RSTORE.ECODE","asc":true},{"name":"CP_C_RSTORE.ID","asc":true}],"range":10})
            String ids = "";
            for (int i = 0; i < objids.size(); i++) {
                ids += objids.getString(i) + ",";
            }
            if (ids != null && ids.length() > 1) {
                ids = ids.substring(0, ids.length() - 1);
            }
            ids = "in (" + ids + ")";
            log.debug("===============>ids：" + ids);
            if (searchdataJo.containsKey("fixedcolumns")) {
                JSONObject fixedcolumns = searchdataJo.getJSONObject("fixedcolumns");
                fixedcolumns.put("ID", ids);
            } else {
                JSONObject fixedcolumns = new JSONObject();
                fixedcolumns.put("ID", ids);
                searchdataJo.put("fixedcolumns", fixedcolumns);
            }
        }

        int startindex = 0;//开始
        int range = 100;//一次处理100
        searchdataJo.put("startindex", startindex);
        searchdataJo.put("range", range);
        searchdataJo.put("isdroplistsearch", true);
        JSONObject fkdrplist = new JSONObject();
        JSONArray searchcols = new JSONArray();
        //需设置修改的字段
        searchcols.add("ID");
        for (String key : fields.keySet()) {
            searchcols.add(key);
        }
        fkdrplist.put("searchcols", searchcols);
        searchdataJo.put("fkdrplist", fkdrplist);
        //

        try {
            JSONArray errJa = new JSONArray();
            JSONObject result = queryBatchData(searchdataJo, qsession, userWeb, table, tm);
            if (result == null || result.size() <= 0 || result.getJSONArray("row").size() <= 0){
                JSONObject errObject = new JSONObject();
                errObject.put("message", "没查询到需要修改的数据," + "查询条件：" + searchdataJo.toJSONString() + " table:" + table.getName() );
                errJa.add(errObject);
                resultHolder.put("code", -1);
                resultHolder.put("error", errJa);
                resultHolder.put("message", "没查询到需要修改的数据");
                return resultHolder.toJSONObject();
            }
            JSONArray befores = getBefores(result, searchcols, table);
            if (befores == null || befores.size() <= 0){
                JSONObject errObject = new JSONObject();
                errObject.put("message", "查询修改前的数据为空," + " table:" + table.getName());
                errJa.add(errObject);
            }

            batchSave(befores, request, qsession, table, afterJo, data, errJa);

            //需分页
            int totalRowCount = result.getInteger("totalRowCount");
            if (totalRowCount > 100) {
                int page = totalRowCount % 100 == 0 ? totalRowCount / 100 : totalRowCount / 100 + 1;
                for (int i = 1; i < page; i++) {
                    searchdataJo.put("startindex", i * range);
                    //
                    result = queryBatchData(searchdataJo, qsession, userWeb, table, tm);
                    if (result == null || result.size() <= 0 || result.getJSONArray("row").size() <= 0){
                        JSONObject errObject = new JSONObject();
                        errObject.put("message", "没查询到需要修改的数据," + "查询条件：" + searchdataJo.toJSONString() + " table:" + table.getName() );
                        errJa.add(errObject);
                        continue;
                    }
                    befores = getBefores(result, searchcols, table);
                    if (befores == null || befores.size() <= 0){
                        JSONObject errObject = new JSONObject();
                        errObject.put("message", "查询修改前的数据为空," + " table:" + table.getName());
                        errJa.add(errObject);
                    }
                    batchSave(befores, request, qsession, table, afterJo, data, errJa);
                }
            }

            if (errJa.size() > 0) {
                resultHolder.put("code", -1);
                resultHolder.put("error", errJa);
                resultHolder.put("message", "修改成功记录数：" + (totalRowCount - errJa.size()) + "，修改失败记录数：" + errJa.size());
            } else {
                resultHolder.put("code", 0);
                resultHolder.put("message", "修改成功记录数：" + totalRowCount);

            }

        } catch (Exception e) {
            log.error(e.getMessage(),e);

            if(e instanceof NDSException){
                resultHolder.put("code",-1);
                resultHolder.put("message",((NDSException) e).getSimpleMessage());
            }else{
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                e.printStackTrace(pw);
                resultHolder.put("code",-2);
                resultHolder.put("message",sw.toString().replace("\n","<br/>")
                        .replace("\tat",""));
            }
        }


        return resultHolder.toJSONObject();

    }

    private JSONObject queryBatchData(JSONObject searchdataJo, QuerySession qsession, UserImpl userWeb, Table table, TableManager tm) throws Exception {

        log.debug("searchdataJo=========>" + searchdataJo.toJSONString());
        //
        QueryRequest query = AjaxUtils.parseQuery(searchdataJo, qsession, userWeb.getId(), userWeb.getLocale(), table);
        //配销中心数据权限   CP_C_DISTRIB_ID
        JSONObject tabprop = table.getJSONProps();
        if (tabprop != null && tabprop.containsKey("precolnames")) {
            JSONArray precolnames = Permissions.filterDataPermissons(table);
            if (precolnames != null && !userWeb.isAdmin()) {
                for (int i = 0; i < precolnames.size(); i++) {
                    JSONObject preCol = precolnames.getJSONObject(i);
                    setdataprem(userWeb, table, preCol.getString("premtype"), tm, query);
                }
            }
        }
        log.debug("query.toSQL=========>" + query.toSQL());
        QueryResult qr = QueryEngine.getInstance().doQuery(query);
        JSONObject result = qr.getColumnDataObj(true);
        log.debug("queryBatchData.result===============>" + result.toJSONString());
//          返回的结果 result {"start":0,"isFullRangeSubTotalEnabled":false,"totalRowCount":2,"rowCount":2,"row":[{"PS_C_BRAND_IDS":{"val":"海之蓝,show","reftablename":"PS_C_BRAND","reftableid":23051,"reftabdesc":"品牌","refobjid":"415,416","colid":136932,"isfk":true},"ID":{"val":"421"}},{"PS_C_BRAND_IDS":{"val":"海之蓝,show","reftablename":"PS_C_BRAND","reftableid":23051,"reftabdesc":"品牌","refobjid":"415,416","colid":136932,"isfk":true},"ID":{"val":"2000043"}}],"queryDesc":"(( (ID in (2000043,421))  并且  (启用 含有 Y) ) 并且  (配销中心= 1112) )"}
//        String id = String.valueOf(dataObject.get("b0"));
//        if (result == null) {
//            throw new NDSException("没有需要修改的数据，请重试！");
//        }
        //
        return result;

    }

    private JSONArray getBefores(JSONObject result, JSONArray searchcols, Table table) {

        JSONArray befores = new JSONArray();
        JSONArray row = result.getJSONArray("row");
        if (row == null || row.size() <= 0) {
            log.debug("===============>getBefores row is null");
            return null;
        }
//         data:{"CP_C_RSTORE":{"PS_C_BRAND_IDS":"416,420"}}
//        after:{"CP_C_RSTORE":{"PS_C_BRAND_IDS":"第二品牌,show","ISOUT":"1"}}
        for (int i = 0; i < row.size(); i++) {
            JSONObject rowObject = row.getJSONObject(i);
            JSONObject searchcolBeforObject = new JSONObject();
            for (int j = 0; j < searchcols.size(); j++) {
                String searchcol = searchcols.getString(j);
                JSONObject searchcolObject = rowObject.getJSONObject(searchcol);
                if (searchcolObject == null) {
                    continue;
                }
                String val = searchcolObject.getString("val");
                searchcolBeforObject.put(searchcol, val);
            }
            JSONObject tablenameObject = new JSONObject();
            tablenameObject.put(table.getName(), searchcolBeforObject);
            befores.add(tablenameObject);
        }

        log.debug("===============>befores：" + befores.toJSONString());

        return befores;
    }

    private JSONArray batchSave(JSONArray befores, HttpServletRequest request, QuerySession qsession, Table table, JSONObject afterJo, String data, JSONArray errJa) throws Exception {

        if (befores == null) {
            log.debug("===============>befores is null");
            return errJa;
        }

        //循环修改数据
        for (int i = 0; i < befores.size(); i++) {
            //获取id
            JSONObject beforeObject = befores.getJSONObject(i);
            JSONObject tablenameObject = beforeObject.getJSONObject(table.getName());
            Long objid = tablenameObject.getLongValue("ID");
            tablenameObject.remove("ID");

            try {
                //
                if (objid == null || objid <= 0) {
                    JSONObject errObject = new JSONObject();
                    errObject.put("objid", objid);
                    errObject.put("message", "objid is error");
                    errJa.add(errObject);
                    continue;
                }
                JSONObject fixcolumn = JSON.parseObject(data);
                JSONObject jor = new JSONObject();
                jor.put("objid", objid);
                jor.put("fixcolumn", fixcolumn);
                jor.put("table", table.getName());
                jor.put("beforevalue", beforeObject);
                jor.put("aftervalue", afterJo);

                TriggerHolder.VersionedTrigger trigger = table.getTrigger("TRI");
                if (trigger != null) {
                    jor.put("aspecttrigger", trigger.toJSONObject());
                }
                DefaultWebEvent event = new DefaultWebEvent("doSave", request, false);
                event.put("param", jor);
                ValueHolder valueHolder = handle.process(jor, qsession, event, "save");
                int code = Tools.getInt(String.valueOf(valueHolder.get("code")), 0);
                if (code != 0) {
                    JSONObject errObject = new JSONObject();
                    errObject.put("objid", objid);
                    errObject.put("message", valueHolder.get("message"));
                    errJa.add(errObject);
                }
            } catch (Exception e) {
                log.error(e.getMessage(),e);
                JSONObject errObject = new JSONObject();
                if(e instanceof NDSException){
                    errObject.put("code",-1);
                    errObject.put("message",((NDSException) e).getSimpleMessage());
                }else{
                    StringWriter sw = new StringWriter();
                    PrintWriter pw = new PrintWriter(sw);
                    e.printStackTrace(pw);
                    errObject.put("code",-2);
                    errObject.put("message",sw.toString().replace("\n","<br/>")
                            .replace("\tat",""));
                }
                errJa.add(errObject);
            }
        }

        return errJa;

    }


    private void setdataprem(User userWeb, Table table, String colname, TableManager tm, QueryRequest query) {

        ColumnLink clink = null;

        List<Long> distribids = getWritableDatas(colname,userWeb.getId());

        try {
            clink = table.getColumn(colname).getColumnLink(tm);
            String cond = Arrays.asList(distribids).toString().replace("[", "").replace("]", "");

            log.debug("cond ->" + cond + " USER->" + userWeb.getName() + " distribids->" + distribids);
            //Tools.getStr4SQLINParam(distribids);
            if (Validator.isNotNull(cond)) {
                cond = "IN (" + cond + ")";
                Expression expr2 = new Expression(clink, cond, null);
                query.addParam(expr2);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }


}